/**
 * 判断一个对象是否为空对象的多种方法
 */

// 方法1：使用Object.keys()
function isEmpty1(obj) {
  // 先判断是否为对象且不为null
  if (typeof obj !== 'object' || obj === null) {
    return false; // 不是对象或为null，返回false
  }
  return Object.keys(obj).length === 0;
}

// 方法2：使用for...in循环
function isEmpty2(obj) {
  // 先判断是否为对象且不为null
  if (typeof obj !== 'object' || obj === null) {
    return false; // 不是对象或为null，返回false
  }
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      return false; // 有自身属性，不为空
    }
  }
  return true; // 没有自身属性，为空
}

// 方法3：使用JSON.stringify()
function isEmpty3(obj) {
  // 先判断是否为对象且不为null
  if (typeof obj !== 'object' || obj === null) {
    return false; // 不是对象或为null，返回false
  }
  return JSON.stringify(obj) === '{}';
}

// 方法4：使用Object.getOwnPropertyNames()
function isEmpty4(obj) {
  // 先判断是否为对象且不为null
  if (typeof obj !== 'object' || obj === null) {
    return false; // 不是对象或为null，返回false
  }
  return Object.getOwnPropertyNames(obj).length === 0;
}

// 方法5：使用Object.entries()
function isEmpty5(obj) {
  // 先判断是否为对象且不为null
  if (typeof obj !== 'object' || obj === null) {
    return false; // 不是对象或为null，返回false
  }
  return Object.entries(obj).length === 0;
}

// 测试
const emptyObj = {};
const nonEmptyObj = { key: 'value' };
const objWithProto = Object.create({ a: 1 }); // 只有原型属性的对象

console.log('--- 空对象测试 ---');
console.log('Object.keys():', isEmpty1(emptyObj));
console.log('for...in:', isEmpty2(emptyObj));
console.log('JSON.stringify():', isEmpty3(emptyObj));
console.log('Object.getOwnPropertyNames():', isEmpty4(emptyObj));
console.log('Object.entries():', isEmpty5(emptyObj));

console.log('--- 非空对象测试 ---');
console.log('Object.keys():', isEmpty1(nonEmptyObj));
console.log('for...in:', isEmpty2(nonEmptyObj));
console.log('JSON.stringify():', isEmpty3(nonEmptyObj));
console.log('Object.getOwnPropertyNames():', isEmpty4(nonEmptyObj));
console.log('Object.entries():', isEmpty5(nonEmptyObj));

console.log('--- 只有原型属性的对象测试 ---');
console.log('Object.keys():', isEmpty1(objWithProto));
console.log('for...in:', isEmpty2(objWithProto)); // 注意：for...in会遍历原型链，但hasOwnProperty只检查自身属性
console.log('JSON.stringify():', isEmpty3(objWithProto));
console.log('Object.getOwnPropertyNames():', isEmpty4(objWithProto));
console.log('Object.entries():', isEmpty5(objWithProto));

// 注意：如果需要考虑Symbol属性，可以使用Object.getOwnPropertySymbols()
const objWithSymbol = { [Symbol('key')]: 'value' };
console.log('--- 只有Symbol属性的对象测试 ---');
console.log('Object.keys():', isEmpty1(objWithSymbol)); // true (不考虑Symbol)
console.log('Object.getOwnPropertySymbols().length:', Object.getOwnPropertySymbols(objWithSymbol).length === 0); // false

// 完整版：考虑Symbol属性的空对象检查
function isCompletelyEmpty(obj) {
  if (typeof obj !== 'object' || obj === null) {
    return false;
  }
  return Object.keys(obj).length === 0 && 
         Object.getOwnPropertySymbols(obj).length === 0;
}

console.log('完整版(考虑Symbol):', isCompletelyEmpty(objWithSymbol)); // false 